#ifdef _WIN32
    #include <winsock2.h>
    #include <windows.h>
#endif
#include "utils.h"
#include <sstream>
#include <algorithm>
#include <time.h>
#include <string.h>
#include <stdlib.h>
#include <boost/regex.hpp>

namespace uesdk{

uint64_t GetCurrentMS(){
    return GetTickCount();
}

std::string Time2Str(time_t ts, const std::string& format) {
    struct tm t;
    localtime_s(&t,&ts);
    char buf[64];
    strftime(buf,sizeof(buf), format.c_str(), &t);
    return buf;
}


std::string Gmtime2Str(time_t ts, const std::string& format) {
    struct tm t;
    gmtime_s(&t,&ts);
    char buf[64];
    strftime(buf,sizeof(buf), format.c_str(), &t);
    return buf;
}

std::string StringUtil::trim(const std::string& str,const std::string& delimit){
	std::size_t begin = str.find_first_not_of(delimit);
    if(begin == std::string::npos){
        return "";
    }
    std::size_t end = str.find_last_not_of(delimit);
    return str.substr(begin, end - begin + 1);
}

std::vector<std::string> StringUtil::split(const std::string& str, char delim, size_t max){
    std::vector<std::string> result;
    if(str.empty()){
        return result;
    }
    size_t last = 0;
    size_t pos = str.find(delim);
    while(pos != std::string::npos){
        result.push_back(str.substr(last, pos - last));
        last = pos + 1;
        if(--max == 1){
            break;
        }
        pos = str.find(delim,last);
    }
    result.push_back(str.substr(last));
    return result;
}

std::vector<std::string> StringUtil::split(const std::string& str, const char* delim, size_t max){
    std::vector<std::string> result;
    if(str.empty()){
        return result;
    }
    size_t last = 0;
    size_t pos = str.find_first_of(delim);
    while(pos != std::string::npos){
        result.push_back(str.substr(last, pos - last));
        last = pos + 1;
        if(--max == 1){
            break;
        }
        pos = str.find_first_of(delim,last);
    }
    result.push_back(str.substr(last));
    return result;
}

std::string StringUtil::replace(const std::string& src, char find, char replaceWitch){
	std::string str1 = src;
    std::size_t pos = str1.find(find);
    while(pos != std::string::npos){
        str1[pos] = replaceWitch;
        pos = str1.find(find,pos + 1);
    }
    return str1;
}

std::string StringUtil::replace(const std::string& src, char find, const std::string& replaceWitch){
    std::stringstream ss;
    size_t index = 0;
    size_t pos = src.find(find);
    while(pos != std::string::npos){
        ss << src.substr(index,pos - index);
        ss << replaceWitch;
        index = pos + 1;
        pos = src.find(find,index);
    }
    ss << src.substr(index);
    return ss.str();
}

std::string StringUtil::toLower(const std::string& v) {
    std::string rt = v;
    std::transform(rt.begin(),rt.end(),rt.begin(), ::tolower);
    return rt;
}

std::string StringUtil::toUpper(const std::string& v) {
    std::string rt = v;
    std::transform(rt.begin(),rt.end(),rt.begin(), ::toupper);
    return rt;
}

std::vector<std::string> StringUtil::regexSearch(const std::string& src,const std::string& pattern) {
    boost::regex regexPattern(pattern);
    std::vector<std::string> result;
    boost::sregex_token_iterator iter (src.begin(),src.end(),regexPattern);
    while(iter != boost::sregex_token_iterator()){
        result.push_back(*iter);
        ++iter;
    }

    return result;

}

bool StringUtil::regexMatch(const std::string& src,const std::string& pattern){
    boost::regex regexPattern(pattern);
    bool match = boost::regex_match(src,regexPattern);
    return match;
}

std::string StringUtil::regexReplace(const std::string& src, const std::string& pattern, const std::string& replaceWitch) {
    boost::regex regexPattern(pattern);
    std::string result = boost::regex_replace(src,regexPattern,replaceWitch);
    return result;
}

bool TypeUtil::isPhoneNumber(const std::string& phone){
    return StringUtil::regexMatch(phone,"(13[0-9]|14[01456879]|15[0-35-9]|16[2567]|17[0-8]|18[0-9]|19[0-35-9])\\d{8}");
}

bool TypeUtil::isEmail(const std::string& email){
    return StringUtil::regexMatch(email,"^[A-Za-z0-9\\u4e00-\\u9fa5]+@[a-zA-Z0-9_-]+(.[a-zA-Z0-9_-]+)+$");
}
    
} // namespace uesdk
 